﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Octopus.Logging.Commons;

namespace Octopus.Logging.Impl.Text.Common.IO
{
    public class QuietTextWriter
    {
        private string fileName = null;
        private bool isAppend = false;
        private bool isFlush = false;
        private StringBuilder content = null;

        #region Public Instance Constructors

        /// <summary>
        /// Create a new QuietTextWriter using a writer and error handler
        /// </summary>
        /// <param name="writer">the writer to actually write to</param>
        /// <param name="errorHandler">the error handler to report error to</param>
        public QuietTextWriter(string file,bool append,int flushTimeSpan )
        {
            fileName = file;
            isAppend = append;
            nFlushTimeSpan = flushTimeSpan;

            caller = new TimeCaller();
            if (nFlushTimeSpan >0)
            {
                isFlush = true;
                content = new StringBuilder();
                caller.Start(nFlushTimeSpan, RealFlush);
            }
        }

        #endregion Public Instance Constructors

        #region Public Instance Properties
        /// <summary>
        /// Gets a value indicating whether this writer is closed.
        /// </summary>
        /// <value>
        /// <c>true</c> if this writer is closed, otherwise <c>false</c>.
        /// </value>
        public bool Closed
        {
            get { return m_closed; }
        }

        #endregion Public Instance Properties

        #region Protected Instance Properties

        /// <summary>
        /// Gets the underlying <see cref="TextWriter" />.
        /// </summary>
        /// <value>
        /// The underlying <see cref="TextWriter" />.
        /// </value>
        protected TextWriter Writer
        {
            get { return this.m_writer; }
        }

        #endregion Protected Instance Properties

        #region Public Instance Methods

        /// <summary>
        /// Writes a string to the output.
        /// </summary>
        /// <param name="value">The string data to write to the output.</param>
        virtual public void Write(string value)
        {
            if(string.IsNullOrEmpty(value)){return ;}

            if (content.Length + value.Length > content.MaxCapacity)
            {
                RealFlush();
            }

            content.AppendLine(value);
        }

        /// <summary>
        /// Flushes any buffered output.
        /// </summary>
        public void Flush()
        {
            if (nFlushTimeSpan == 0)
            {
                RealFlush();
            }
        }

        private void RealFlush()
        {
            if (content.Length > 0)
            {
                using (StreamWriter writer = new StreamWriter(fileName, isAppend, Encoding.UTF8))
                {
                    lock (content)
                    {
                        writer.Write(content.ToString());
                        content.Length = 0;
                    }
                }
            }
        }

        /// <summary>
        /// Closes the underlying output writer.
        /// </summary>
        public void Close()
        {
            caller.Stop();
            RealFlush();

            m_closed = true;
            this.Writer.Close();
        }

        #endregion Public Instance Methods

        #region Private Instance Fields



        /// <summary>
        /// The instance of the underlying TextWriter used for output
        /// </summary>
        private TextWriter m_writer;

        /// <summary>
        /// Flag to indicate if this writer is closed
        /// </summary>
        private bool m_closed = false;


        private int nFlushTimeSpan;

        private TimeCaller caller;
        #endregion Private Instance Fields
    }

    
}
